/**
 * 
 */
package mycsveditor.editors;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlink;

/**
 * @author dongxu
 * 
 */
public class JavaCallHyperlinkDetector extends AbstractHyperlinkDetector {

	private JavaAnalysisUtil fJavaAnalysisUtil;

	public JavaCallHyperlinkDetector(JavaAnalysisUtil javaAnalysisUtil) {
		fJavaAnalysisUtil = javaAnalysisUtil;
	}

	static private final Pattern JAVA_CALL_PATTERN = Pattern
			.compile("(?i)^([a-z_][a-z0-9._]+),[a-z0-9_]+(?=$|,)");

	@Override
	public IHyperlink[] detectHyperlinks(ITextViewer textViewer,
			IRegion region, boolean canShowMultipleHyperlinks) {
		if (!isValidLink(textViewer, region)) {
			return null;
		}

		LineInfo lineInfo = new LineInfo(textViewer.getDocument(), region
				.getOffset());


		Matcher m = JAVA_CALL_PATTERN.matcher(lineInfo.getLine());
		if (!m.find()) {
			return null;
		}

		String javaCallString = m.group();
		int javaCallLength = javaCallString.length();
		if (lineInfo.getOffsetInLine() > javaCallLength - 1) {
			return null;
		}

		if (lineInfo.getOffsetInLine() < m.group(1).length()) {
			javaCallLength = m.group(1).length();
			javaCallString = m.group(1);
		}

		IRegion javaCallRegion = new Region(lineInfo.getRegion().getOffset(),
				javaCallLength);
		return new IHyperlink[] { new JavaCallHyperlink(javaCallRegion,
				javaCallString, fJavaAnalysisUtil) };
	}

	private boolean isValidLink(ITextViewer textViewer, IRegion region) {
		if (region == null || textViewer == null)
			return false;

		IDocument document = textViewer.getDocument();
		if (document == null)
			return false;

		try {
			if (!document.getPartition(region.getOffset()).getType().equals(
					CSVPartitionScanner.JAVA_CALL)) {
				return false;
			}
		} catch (BadLocationException e) {
			return false;
		}
		return true;
	}

}
